package com.tjbank.cssys.web.util;

import com.alibaba.fastjson.JSON;
import com.tjbank.cssys.domain.CkOrderLoanIntelligenceDivision;
import com.tjbank.cssys.domain.CkOrderLoanOutsourcing;
import com.tjbank.cssys.domain.CkOrderLoanPeopleDivision;
import com.tjbank.cssys.domain.CkOrderRecoveryData;
import com.tjbank.cssys.repository.CkOrderLoanIntelligenceDivisionMapper;
import com.tjbank.cssys.repository.CkOrderLoanPeopleDivisionMapper;
import com.tjbank.cssys.web.config.ScanningCleaningConfig;
import com.tjbank.cssys.web.service.CkOrderLoanOutsourcingService;
import com.tjbank.cssys.web.service.CkOrderRecoveryDataService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class ReDivisionUtils {
    @Autowired
    private CkOrderLoanIntelligenceDivisionMapper ckOrderLoanIntelligenceDivisionMapper;
    @Autowired
    private ScanningCleaningConfig scanningCleaningConfig;
    @Autowired
    private CkOrderLoanPeopleDivisionMapper ckOrderLoanPeopleDivisionMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private CkOrderLoanOutsourcingService ckOrderLoanOutsourcingService;
    @Autowired
    private FileDownloadUtil fileDownloadUtil;
    @Autowired
    private CkOrderRecoveryDataService ckOrderRecoveryDataService;
    protected static final Logger logger = LoggerFactory.getLogger(ReDivisionUtils.class);

    /**
     * 委外分案
     * @param ids
     * @param model_type
     * @param n_outbound
     * @return
     * @throws Exception
     */
    public boolean outSourcingDivision(String ids, String model_type, Byte n_outbound) throws Exception {
        logger.info("委外分案开始");
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = simpleDateFormat.format(date);
        String[] split = ids.split(",");
        List<CkOrderLoanOutsourcing>  ckOrderLoanOutsourcings=ckOrderLoanOutsourcingService.selectByIds(split);
        List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = new ArrayList<>();
        ckOrderLoanOutsourcings.stream().forEach(ckOrderLoanOutsourcing -> {
            CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision = new CkOrderLoanIntelligenceDivision();
            BeanUtils.copyProperties(ckOrderLoanOutsourcing,ckOrderLoanIntelligenceDivision);
            ckOrderLoanIntelligenceDivisions.add(ckOrderLoanIntelligenceDivision);
        });
        List<CkOrderLoanPeopleDivision> ckOrderLoanPeopleDivisions = ckOrderLoanPeopleDivisionMapper.selectByStatus((byte) 0);
        ckOrderLoanIntelligenceDivisions.stream().forEach(
                ckOrderLoanIntelligenceDivision -> {
                    ckOrderLoanIntelligenceDivision.setOutbound(n_outbound);
                    ckOrderLoanIntelligenceDivision.setCollectionPriority("3");
                });
        try {
            Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> handleMap = getHandleMap(ckOrderLoanIntelligenceDivisions);
            //人工外呼文件生成
            logger.info("人工再次分案生成文件开始");
            peopleFileGeneration(handleMap);
            logger.info("委外分案生成文件结束");
            logger.info("委外分案上传文件开始");
            uploadPeopleCall(dateStr);
            logger.info("委外分案上传文件结束");
            ckOrderLoanPeopleDivisions.stream().forEach(ckOrderLoanPeopleDivision -> ckOrderLoanPeopleDivision.setStatus((byte) 1));
            ckOrderLoanPeopleDivisionMapper.updateList(ckOrderLoanPeopleDivisions);
            logger.info("委外分案结束");
            return true;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 再次分案
     * @param ids
     * @param model_type
     * @param n_outbound
     * @return
     * @throws Exception
     */
    public boolean peopleDivision(String ids, String model_type, Byte n_outbound) throws Exception {
        logger.info("人工再次分案开始");
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = simpleDateFormat.format(date);
        String[] split = ids.split(",");
        List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = ckOrderLoanIntelligenceDivisionMapper.selectByPrimaryKeyLsit(split);
        List<CkOrderLoanPeopleDivision> ckOrderLoanPeopleDivisions = ckOrderLoanPeopleDivisionMapper.selectByStatus((byte) 0);
        ckOrderLoanIntelligenceDivisions.stream().forEach(ckOrderLoanIntelligenceDivision -> {
            ckOrderLoanIntelligenceDivision.setOutbound(n_outbound);
            String overdueGrade = ckOrderLoanIntelligenceDivision.getOverdueGrade();
            ckOrderLoanIntelligenceDivision.setCollectionPriority(overdueGrade.replaceAll("M",""));
        });
        logger.info("短信筛选开始");
        List<String> serialNumbers = new ArrayList<>();
        for (CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision : ckOrderLoanIntelligenceDivisions) {
            String serialNumber = ckOrderLoanIntelligenceDivision.getSerialNumber();
            serialNumbers.add(serialNumber);
        }
        List<CkOrderRecoveryData> ckOrderRecoveryDatas=ckOrderRecoveryDataService.selectBySerialNumber(serialNumbers);
        if (CollectionUtils.isNotEmpty(ckOrderRecoveryDatas)) {
            ckOrderRecoveryDataService.deleteForEach(ckOrderRecoveryDatas);
        }
        logger.info("短信筛选结束");
        try {
            Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> handleMap = getHandleMap(ckOrderLoanIntelligenceDivisions);
            //人工外呼文件生成
            logger.info("人工再次分案生成文件开始");
            peopleFileGeneration(handleMap);
            logger.info("人工再次分案生成文件结束");
            logger.info("人工再次分案上传文件开始");
            uploadPeopleCall(dateStr);
            logger.info("人工再次分案上传文件结束");
            ckOrderLoanPeopleDivisions.stream().forEach(ckOrderLoanPeopleDivision -> ckOrderLoanPeopleDivision.setStatus((byte) 1));
            ckOrderLoanPeopleDivisionMapper.updateList(ckOrderLoanPeopleDivisions);
            logger.info("人工再次分案分案结束");
            return true;
        } catch (Exception e) {
           throw e;
        }
    }
    /**
     * 人工外呼上传
     * @param dateStr
     */
    private void uploadPeopleCall(String dateStr) {
        logger.info("上传人工外呼开始");
        String peopleUploadJsonPath = scanningCleaningConfig.getPeopleUploadJsonPath();
        List<String> peopleUploadFileNameList = getFileNameList(peopleUploadJsonPath);
        if (CollectionUtils.isNotEmpty(peopleUploadFileNameList)) {
            String jsonFileName = null;
            String okFileName = null;
            for (String fileName : peopleUploadFileNameList) {
                if (fileName.contains("json")) {
                    jsonFileName = fileName;
                } else if (fileName.contains("ok")) {
                    okFileName = fileName;
                }
            }
            logger.info("人工上传到oss上json文件开始");
            String localFileNameJosnStr = peopleUploadJsonPath + jsonFileName;
            String uploadJsonName = new StringBuilder(scanningCleaningConfig.getPackageName()).append("reDivision/").append(scanningCleaningConfig.getPrefixUploadJsonPath().replace("yyyyMMdd",dateStr)).toString() ;
            File localFileNameJson = new File(localFileNameJosnStr);
            fileDownloadUtil.uploadOSS(uploadJsonName, localFileNameJson);
            logger.info("人工上传到oss上json文件结束,上传文件地址为:"+uploadJsonName);
            logger.info("人工上传到oss上ok文件开始");
            String localFileNameOkStr = peopleUploadJsonPath + okFileName;
            String uploadOkName = new StringBuilder(scanningCleaningConfig.getPackageName()).append("reDivision/").append(scanningCleaningConfig.getPrefixUploadJsonPath().replace("yyyyMMdd",dateStr).replace("json","ok")).toString();
            File localFileNameOk = new File(localFileNameOkStr);
            fileDownloadUtil.uploadOSS(uploadOkName, localFileNameOk);
            logger.info("人工上传到oss上ok文件结束,上传文件地址为:"+uploadOkName);
        } else {
            logger.info("人工无上传文件");
        }
        logger.info("上传人工外呼结束");
    }
    /**
     * 获取所上传文件名
     *
     * @param txtPath 当地文件地址
     * @return
     */
    private List<String> getFileNameList(String txtPath) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = simpleDateFormat.format(date);
        File file = new File(txtPath);
        String[] list = file.list();
        logger.info("获取文件名称开始");
        List<String> fileList = new ArrayList<>();
        if (list != null) {
            if (list.length > 0) {
                for (String s : list) {
                    if (s.contains(dateStr)) {
                        fileList.add(s);
                    }
                }
            }
        }

        logger.info("获取文件名称结束,文件名称为:" + JSON.toJSONString(fileList));
        return fileList;
    }
    /**
     * 人工文件生成
     *
     * @param handleMap
     */
    private void peopleFileGeneration(Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> handleMap) throws Exception {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = simpleDateFormat.format(date);
        logger.info("人工外呼生成文件开始");
        Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> peopleMap = new HashMap<>();

        if (handleMap.get("人工外呼") != null) {
            peopleMap.put("人工外呼", handleMap.get("人工外呼"));
        }
        int count = 0;
        for (Map.Entry<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> stringMapEntry : peopleMap.entrySet()) {
            Map<String, List<CkOrderLoanIntelligenceDivision>> value = stringMapEntry.getValue();
            for (Map.Entry<String, List<CkOrderLoanIntelligenceDivision>> stringListEntry : value.entrySet()) {
                List<CkOrderLoanIntelligenceDivision> value1 = stringListEntry.getValue();
                count += value1.size();
            }
        }
        String peopleJsonStr = JSON.toJSONString(peopleMap);
        File peopleJsonFile = new File(scanningCleaningConfig.getPeopleUploadJsonPath());
        if (!peopleJsonFile.exists()) {
            peopleJsonFile.mkdirs();
        }
        String peopleJsonPath = scanningCleaningConfig.getPeopleUploadJsonPath() + scanningCleaningConfig.getPrefixUploadJsonPath().replace("yyyyMMdd", dateStr);
        logger.info("人工外呼生成json文件开始,文件名称为:" + peopleJsonPath);
        writeJsonFile(peopleJsonPath, peopleJsonStr);
        logger.info("人工外呼处理成json格式结束");
        String peopleOkPath = peopleJsonPath.replace("json", "ok");
        logger.info("人工外呼生成ok文件开始,文件名称为:" + peopleOkPath);
        writeJsonFile(peopleOkPath, peopleJsonStr);
        logger.info("人工外呼处理成ok格式结束");
        logger.info("人工外呼存储总条数到redis开始");
        Map<String, Object> redisMap = new HashMap<>();
        redisMap.put("EsbFilePath", scanningCleaningConfig.getPackageName() + "reDivision/" + scanningCleaningConfig.getPrefixUploadJsonPath().replace("yyyyMMdd", dateStr));
        redisMap.put("EsbCount", count);
        redisService.hmset("EsbFilePathAndCount", redisMap);
        logger.info("人工外呼存储总条数到redis结束");
        logger.info("人工外呼生成文件结束");
    }


    /**
     * 生成json文件
     *
     * @param filePath
     * @param sets
     * @return
     * @throws Exception
     */
    private boolean writeJsonFile(String filePath, String sets) throws Exception {
        FileWriter fw;
        fw = new FileWriter(filePath);
        PrintWriter out = new PrintWriter(fw);
        try {
            out.write(sets);
            out.println();
            return true;
        } catch (Exception e) {
            throw e;
        } finally {
            fw.close();
            out.close();
        }

    }

    private Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> getHandleMap(List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions) throws Exception {
        Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> resultMap = new HashMap<>();
        Map<String, List<CkOrderLoanIntelligenceDivision>> params = new HashMap<>();
        for (CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision : ckOrderLoanIntelligenceDivisions) {
            String peopleId = ckOrderLoanIntelligenceDivision.getPeopleId();
            if (params.get(peopleId) == null) {
                List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisionList = new ArrayList<>();
                ckOrderLoanIntelligenceDivisionList.add(ckOrderLoanIntelligenceDivision);
                params.put(peopleId, ckOrderLoanIntelligenceDivisionList);
            } else {
                List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisionList = params.get(peopleId);
                ckOrderLoanIntelligenceDivisionList.add(ckOrderLoanIntelligenceDivision);
                params.put(peopleId, ckOrderLoanIntelligenceDivisionList);
            }
        }
        for (Map.Entry<String, List<CkOrderLoanIntelligenceDivision>> stringListEntry : params.entrySet()) {
            List<CkOrderLoanIntelligenceDivision> value = stringListEntry.getValue();
            Byte b = 1;
            for (CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision : value) {
                Byte outbound = ckOrderLoanIntelligenceDivision.getOutbound();
                if (b <= outbound) {
                    b = outbound;
                }
            }
            for (CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision : value) {
                resultMap = getRulesMap(ckOrderLoanIntelligenceDivision, b, resultMap);
            }
        }
        return resultMap;
    }

    /**
     * 生成规则Map
     *
     * @param ckOrderLoanIntelligenceDivision
     * @param result
     * @param rulesMap
     * @return
     */
    private Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> getRulesMap(CkOrderLoanIntelligenceDivision ckOrderLoanIntelligenceDivision,
                                                                                        Byte result,
                                                                                        Map<String, Map<String, List<CkOrderLoanIntelligenceDivision>>> rulesMap) throws Exception {
        String resultStr = null;
        switch (result) {
            case (byte) 1:
                resultStr = "金信通";
                break;
            case (byte) 2:
                resultStr = "智能外呼";
                break;
            case (byte) 3:
                resultStr = "人工外呼";
                break;
            case (byte) 4:
                resultStr = "委外";
                break;
            case (byte) 5:
                resultStr = "错误";
                break;
        }
        String peopleId = ckOrderLoanIntelligenceDivision.getPeopleId();
        if (rulesMap.get(resultStr) == null) {
            List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = new ArrayList<>();
            Map<String, List<CkOrderLoanIntelligenceDivision>> peopleIdMap = new HashMap<>();
            ckOrderLoanIntelligenceDivisions.add(ckOrderLoanIntelligenceDivision);
            peopleIdMap.put(peopleId, ckOrderLoanIntelligenceDivisions);
            rulesMap.put(resultStr, peopleIdMap);
        } else {
            Map<String, List<CkOrderLoanIntelligenceDivision>> peopleIdMap = rulesMap.get(resultStr);
            if (peopleIdMap.get(peopleId) == null) {
                List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = new ArrayList<>();
                ckOrderLoanIntelligenceDivisions.add(ckOrderLoanIntelligenceDivision);
                peopleIdMap.put(peopleId, ckOrderLoanIntelligenceDivisions);
                rulesMap.put(resultStr, peopleIdMap);
            } else {
                List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = peopleIdMap.get(peopleId);
                ckOrderLoanIntelligenceDivisions.add(ckOrderLoanIntelligenceDivision);
                peopleIdMap.put(peopleId, ckOrderLoanIntelligenceDivisions);
                rulesMap.put(resultStr, peopleIdMap);
            }
        }
        return rulesMap;

    }
}
